import copy
import math

import numpy as np

import Super
import Target
import archiving
import load
import config
import update

particals = config.particals  # 种群数量
MaxIter = config.MaxIter  # 最大迭代次数
# archive_size = config.archive_size  # 存储库储存上限数量
beta = config.beta  # 成年狮所占比列
Nc = config.Nc  # 成年狮母狮数量
Np = config.Np  # 幼师数量
dim = config.dim  # 维度，优化变量的个数

'''狮群算法'''
'''加入单双周和起始周'''


def MOLSO(task_list, students, teachers, classroom_list, buildings_dis):
    x = []
    y1 = []
    y2 = []
    y3 = []
    # 优化变量的上下界
    lb = np.ones([dim, 1])  # 下边界，课程数、时间数、教室数应该都是整数，所以下边界不存在负数
    ub = len(task_list) * np.ones([dim, 1])  # 上边界,课程的数量
    # 狮子活动范围空间各维度的最小值和最大值
    # lb = np.ones([dim, 1])
    # ub = [[config.num_days * config.periods_per_day], [len(classroom_list)]]

    # 初始化种群
    schemesList, RTmatrix_filled, STmatrix_filled, TTmatrix_filled = load.Load(task_list, students, teachers,
                                                                               classroom_list, particals)
    # 复制种群
    copy_schemesList = copy.deepcopy(schemesList)

    # init_RTmatrix_filled = copy.deepcopy(RTmatrix_filled)
    # init_STmatrix_filled = copy.deepcopy(STmatrix_filled)
    # init_TTmatrix_filled = copy.deepcopy(TTmatrix_filled)
    # 计算适应度
    '''适应度计算需要讨论  spf  已修改!!!!!!!!!'''
    '''加入单双周和起始周修改  SPF  2024.5.9'''
    # fitness = Target.target_fun(copy_schemesList, buildings_dis, len(student_list), len(teacher_list))
    fitness = Target.target_fun(RTmatrix_filled, STmatrix_filled, TTmatrix_filled, buildings_dis, len(students),
                                len(teachers))

    # 多目标问题pareto解  已修改！！！！！！！！！！！
    newParetofrontiers = Super.super(fitness)

    # 初始化个体最优，初始是个体最优就是狮子本身
    lion_p, RTlion_p, fitness_p, s_t_p, t_t_p = init_pbest(copy_schemesList, RTmatrix_filled, fitness,
                                                           STmatrix_filled, TTmatrix_filled)

    # 快速非支配排序和拥挤距离排序，确定全局最优,即狮王的位置
    lion_g, lion_fitness, RTlion_g = archiving.init_archive(copy_schemesList, newParetofrontiers, RTmatrix_filled)

    # 进行迭代,位置更新，然后计算适应度，更新全局最优
    for t in range(MaxIter):
        update_RTmatrix = []  # 存储此次迭代过程中修改位置后的矩阵列表
        update_schemeslist = []  # 存储迭代过程中修改课程信息后方案的列表
        update_STmatrix_filled = []
        update_TTmatrix_filled = []
        step_ = config.step_factory * (np.mean(ub) - np.mean(lb))  # 步长
        # 母狮扰动因子
        alphaf = int(step_ * np.exp(- 30 * t / MaxIter) ** 10)  # 决定变换课程的数量，母狮扰动因子
        # 幼狮扰动因子
        alphac = int(step_ * (MaxIter - t) / MaxIter)
        # 母狮位置更新（这里取的母狮是前Nc个狮子）
        for i in range(Nc):
            update_ST = copy.deepcopy(s_t_p[i])  # 第i个方案对应的学生上课情况方案（第i个母狮）
            update_TT = copy.deepcopy(t_t_p[i])
            matrix_a = copy.deepcopy(RTlion_p[i])  # 此处应该为第t-1次的个体a的历史最佳位置
            update_scheme = copy.deepcopy(lion_p[i])
            index = i
            while index == i:
                index = np.random.randint(0, Nc)  # 随机挑选一只母狮
                # 找不是自己的母狮
                if index != i:
                    lion_b_pbest = RTlion_p[index]  # 获取随机母狮的历史最优解
                    for k in range(alphaf):
                        index_num = np.random.randint(0, len(task_list))  # 随机产生一个变化的课程index号,上限应为课程数
                        task_num = task_list[index_num][0]  # 教学任务号
                        stus = task_list[index_num][6]  # 教学任务学生人数
                        tea = task_list[index_num][3]  # 教学任务教师
                        start_week = task_list[index_num][7]  # 教学任务开始周
                        end_week = task_list[index_num][8]  # 教学任务结束周
                        week_type = task_list[index_num][11]  # 教学任务周类型
                        # 在 当前狮子排课方案RT表中找到task_num号课程的位置，位置存储在positions_a，找开始周的教室时间片
                        positions_a = find_all_element_positions(matrix_a, task_num, start_week)
                        # 在矩阵b中找到course_num号课程的行号，列号,如果课程有多次课，那么位置应该有多个，位置列表positions
                        positions_b = find_all_element_positions(lion_b_pbest, task_num, start_week)
                        count = len(positions_b)
                        if (positions_b == positions_a):
                            continue
                        # 判断矩阵a中b_row和b_col的位置是否为空,如果有多个位置，可能有的位置为空，有的位置不为空，循环遍历
                        for l in range(count):
                            if positions_a == positions_b:
                                break
                            # 逼近位置
                            if abs(positions_a[0][0] - positions_b[0][0]) == 1 and abs(
                                    positions_a[0][1] - positions_b[0][1]) == 1:
                                trans_position = positions_b[0]
                            if abs(positions_a[0][0] - positions_b[0][0]) == 1 and abs(
                                    positions_a[0][1] - positions_b[0][1]) != 1:
                                trans_position = (positions_b[0][0],
                                                  math.ceil((positions_a[0][1] + positions_b[0][1]) / 2))
                            if abs(positions_a[0][0] - positions_b[0][0]) != 1 and abs(
                                    positions_a[0][1] - positions_b[0][1]) == 1:
                                trans_position = (math.ceil((positions_a[0][0] + positions_b[0][0]) / 2),
                                                  positions_b[0][1])
                            if abs(positions_a[0][0] - positions_b[0][0]) != 1 and abs(
                                    positions_a[0][1] - positions_b[0][1]) != 1:
                                trans_position = tuple(
                                    math.ceil((a + b) / 2) for a, b in zip(positions_a[0], positions_b[0]))
                            if classroom_list[trans_position[0]][1] >= len(stus):
                                #  判断冲突
                                conflict = is_conflict(matrix_a, update_ST, update_TT, trans_position,
                                                       start_week, end_week, week_type, students, teachers, stus, tea)
                                # 如果没有冲突
                                if not conflict:
                                    # 如果矩阵a中b_row和b_col的位置为空，则将矩阵a中原有task_num号课程删除，
                                    # 将把b_row和b_col位置变为task_num号课程，否则进行下一次

                                    # 如果以上的冲突都没有发生就变换位置
                                    # 删除一个矩阵a中的课程，并且根据b的位置交换课程位置
                                    matrix_a, update_ST, update_TT = update_timetable(matrix_a, update_ST, update_TT,
                                                                                      positions_a[0], trans_position,
                                                                                      start_week, end_week, week_type,
                                                                                      students, teachers, stus, tea,
                                                                                      task_num, classroom_list)

                                    # 当对一个教学任务进行改变后，修改update_scheme表i号排课方案中task_num课程的上课信息
                                    update_task = update.updated_scheme(update_scheme[index_num], positions_a[0],
                                                                        trans_position, classroom_list)
                                    # 替换排课方案中教学任务信息
                                    update_scheme[index_num] = update_task
                            del positions_a[0]
                            del positions_b[0]
                else:
                    continue

            update_RTmatrix.append(matrix_a)
            update_STmatrix_filled.append(update_ST)
            update_TTmatrix_filled.append(update_TT)
            update_schemeslist.append(update_scheme)

        # 幼狮位置更新
        for y in range(Nc, particals):
            # 生成0-1之间的随机数决定幼狮的移动方向
            q = np.random.random()
            matrix_c = copy.deepcopy(RTlion_p[y])
            update_ST = copy.deepcopy(s_t_p[y])  # 第i个方案对应的学生上课情况方案
            update_TT = copy.deepcopy(t_t_p[y])
            update_scheme = copy.deepcopy(lion_p[y])
            if q < 1 / 3:
                lion_g_matricx = RTlion_g
                for k in range(alphac):
                    index_num = np.random.randint(0, len(task_list))  # 随机产生一个变化的课程号,上限应为课程数
                    task_num = task_list[index_num][0]
                    stus = task_list[index_num][6]  # 教学任务学生人数
                    tea = task_list[index_num][3]  # 教学任务教师
                    start_week = task_list[index_num][7]  # 教学任务开始周
                    end_week = task_list[index_num][8]  # 教学任务结束周
                    week_type = task_list[index_num][11]  # 教学任务周类型
                    # 在矩阵a中找到task_num号课程的位置，位置存储在positions_a
                    positions_c = find_all_element_positions(matrix_c, task_num, start_week)
                    # 在狮王矩阵中找到course_num号课程的行号，列号,如果课程有多次课，那么位置应该有多个，位置列表positions
                    positions_g = find_all_element_positions(lion_g_matricx, task_num, start_week)
                    count = len(positions_g)
                    if positions_c == positions_g:
                        continue
                    # 判断矩阵a中b_row和b_col的位置是否为空,如果有多个位置，可能有的位置为空，有的位置不为空，循环遍历
                    for l in range(count):
                        if positions_c == positions_g:
                            break
                        # 逼近位置
                        if abs(positions_c[0][0] - positions_g[0][0]) == 1 and abs(
                                positions_c[0][1] - positions_g[0][1]) == 1:
                            trans_position = positions_g[0]
                        if abs(positions_c[0][0] - positions_g[0][0]) == 1 and abs(
                                positions_c[0][1] - positions_g[0][1]) != 1:
                            trans_position = (positions_g[0][0],
                                              math.ceil((positions_c[0][1] + positions_g[0][1]) / 2))
                        if abs(positions_c[0][0] - positions_g[0][0]) != 1 and abs(
                                positions_c[0][1] - positions_g[0][1]) == 1:
                            trans_position = (math.ceil((positions_c[0][0] + positions_g[0][0]) / 2),
                                              positions_g[0][1])
                        if abs(positions_c[0][0] - positions_g[0][0]) != 1 and abs(
                                positions_c[0][1] - positions_g[0][1]) != 1:
                            trans_position = tuple(
                                math.ceil((a + b) / 2) for a, b in zip(positions_c[0], positions_g[0]))
                        if classroom_list[trans_position[0]][1] >= len(stus):
                            conflict = is_conflict(matrix_c, update_ST, update_TT, trans_position,
                                                   start_week, end_week, week_type, students, teachers, stus, tea)
                            if not conflict:
                                # 如果矩阵a中b_row和b_col的位置为空，则将矩阵a中原有task_num号课程删除，
                                # 将和b_row和b_col位置变为task_num号课程，否则重新产生一个新的task_num
                                matrix_c, update_ST, update_TT = update_timetable(matrix_c, update_ST, update_TT,
                                                                                  positions_c[0], trans_position,
                                                                                  start_week, end_week, week_type,
                                                                                  students, teachers, stus, tea,
                                                                                  task_num,
                                                                                  classroom_list)  # 删除一个矩阵a中的课程

                                # 当对一个课程号课程进行改变后，修改update_scheme表i号排课方案中task_num课程的上课信息
                                update_task = update.updated_scheme(update_scheme[index_num], positions_c[0],
                                                                    trans_position, classroom_list)
                                # 对于改变课程信息的课程在原有方案中删除，将update_task添加到排课方案列表中
                                update_scheme[index_num] = update_task
                        del positions_c[0]
                        del positions_g[0]

            elif q >= 1 / 3 and q < 2 / 3:
                index = np.random.randint(0, Nc)  # 随机挑选一只母狮,即一个排课方案的序号，找对应序号的排课方案中，适应度值最好的个体
                # 找到狮子个体i对index狮子个体中的与i狮子个体的课程相等的课程号，将i的课程号和index的课程号进行互换，以达到位置更新的作用
                lion_b_pbest = RTlion_p[index]  # 获取随机母狮的历史最优解
                for k in range(alphac):
                    index_num = np.random.randint(0, len(task_list))  # 随机产生一个变化的课程号,上限应为课程数
                    task_num = task_list[index_num][0]
                    stus = task_list[index_num][6]  # 教学任务学生人数
                    tea = task_list[index_num][3]  # 教学任务教师
                    start_week = task_list[index_num][7]  # 教学任务开始周
                    end_week = task_list[index_num][8]  # 教学任务结束周
                    week_type = task_list[index_num][11]  # 教学任务周类型
                    # 在矩阵a中找到task_num号课程的位置，位置存储在positions_a
                    positions_c = find_all_element_positions(matrix_c, task_num, start_week)
                    # 在矩阵b中找到task_num号课程的行号，列号,如果课程有多次课，那么位置应该有多个，位置列表positions
                    positions_b = find_all_element_positions(lion_b_pbest, task_num, start_week)
                    count = len(positions_b)
                    if positions_c == positions_b:
                        continue
                    # 判断矩阵a中b_row和b_col的位置是否为空,如果有多个位置，可能有的位置为空，有的位置不为空，循环遍历
                    for l in range(count):
                        if positions_c == positions_b:
                            break
                        # 逼近位置
                        if abs(positions_c[0][0] - positions_b[0][0]) == 1 and abs(
                                positions_c[0][1] - positions_b[0][1]) == 1:
                            trans_position = positions_b[0]
                        if abs(positions_c[0][0] - positions_b[0][0]) == 1 and abs(
                                positions_c[0][1] - positions_b[0][1]) != 1:
                            trans_position = (positions_b[0][0],
                                              math.ceil((positions_c[0][1] + positions_b[0][1]) / 2))
                        if abs(positions_c[0][0] - positions_b[0][0]) != 1 and abs(
                                positions_c[0][1] - positions_b[0][1]) == 1:
                            trans_position = (math.ceil((positions_c[0][0] + positions_b[0][0]) / 2),
                                              positions_b[0][1])
                        if abs(positions_c[0][0] - positions_b[0][0]) != 1 and abs(
                                positions_c[0][1] - positions_b[0][1]) != 1:
                            trans_position = tuple(
                                math.ceil((a + b) / 2) for a, b in zip(positions_c[0], positions_b[0]))
                        if classroom_list[trans_position[0]][1] >= len(stus):
                            conflict = is_conflict(matrix_c, update_ST, update_TT, trans_position,
                                                   start_week, end_week, week_type, students, teachers, stus, tea)
                            if not conflict:
                                # 如果矩阵a中b_row和b_col的位置为空，则将矩阵a中原有task_num号课程删除，
                                # 将和b_row和b_col位置变为task_num号课程，否则重新产生一个新的task_num
                                matrix_c, update_ST, update_TT = update_timetable(matrix_c, update_ST, update_TT,
                                                                                  positions_c[0], trans_position,
                                                                                  start_week, end_week, week_type,
                                                                                  students, teachers, stus, tea,
                                                                                  task_num,
                                                                                  classroom_list)  # 删除一个矩阵a中的课程

                                # 当对一个课程号课程进行改变后，修改schemesList表i号排课方案中course_num课程的上课信息
                                update_task = update.updated_scheme(update_scheme[index_num], positions_c[0],
                                                                    trans_position, classroom_list)
                                update_scheme[index_num] = update_task
                        del positions_c[0]
                        del positions_b[0]

            else:  # 远离狮王位置活动
                lion_g_matrix = RTlion_g
                for k in range(alphac):
                    index_num = np.random.randint(0, len(task_list))  # 随机产生一个变化的课程号,上限应为课程数
                    task_num = task_list[index_num][0]
                    stus = task_list[index_num][6]  # 教学任务学生人数
                    tea = task_list[index_num][3]  # 教学任务教师
                    start_week = task_list[index_num][7]  # 教学任务开始周
                    end_week = task_list[index_num][8]  # 教学任务结束周
                    week_type = task_list[index_num][11]  # 教学任务周类型
                    # 在矩阵a中找到task_num号课程的位置，位置存储在positions_a
                    positions_c = find_all_element_positions(matrix_c, task_num, start_week)
                    # 在狮王矩阵中找到task_num号课程的行号，列号,如果课程有多次课，那么位置应该有多个，位置列表positions
                    positions_g = find_all_element_positions(lion_g_matrix, task_num, start_week)
                    if positions_c == positions_g:
                        continue
                    # 确定应该放task_num的位置,幼狮位置+（幼狮位置减狮王位置）,如果positions中出现负值，则产生一个新的task_num值
                    # 判断position中的值是否合法
                    positions, new_positions_c = calculate_position(positions_c, positions_g, classroom_list)
                    if len(positions) != 0:
                        count = len(positions)
                        # 判断矩阵a中b_row和b_col的位置是否为空,如果有多个位置，可能有的位置为空，有的位置不为空，循环遍历
                        for l in range(count):
                            if positions == new_positions_c:
                                break
                            # 逼近位置
                            if abs(new_positions_c[0][0] - positions[0][0]) == 1 and abs(
                                    new_positions_c[0][1] - positions[0][1]) == 1:
                                trans_position = positions[0]
                            if abs(new_positions_c[0][0] - positions[0][0]) == 1 and abs(
                                    new_positions_c[0][1] - positions[0][1]) != 1:
                                trans_position = (positions[0][0],
                                                  math.ceil((new_positions_c[0][1] + positions[0][1]) / 2))
                            if abs(new_positions_c[0][0] - positions[0][0]) != 1 and abs(
                                    new_positions_c[0][1] - positions[0][1]) == 1:
                                trans_position = (math.ceil((new_positions_c[0][0] + positions[0][0]) / 2),
                                                  positions[0][1])
                            if abs(new_positions_c[0][0] - positions[0][0]) != 1 and abs(
                                    new_positions_c[0][1] - positions[0][1]) != 1:
                                trans_position = tuple(
                                    math.ceil((a + b) / 2) for a, b in zip(new_positions_c[0], positions[0]))
                            if classroom_list[trans_position[0]][1] >= len(stus):
                                conflict = is_conflict(matrix_c, update_ST, update_TT, trans_position,
                                                       start_week, end_week, week_type, students, teachers, stus, tea)
                                if not conflict:
                                    # 如果矩阵a中b_row和b_col的位置为空，则将矩阵a中原有course_num号课程删除，
                                    # 将和b_row和b_col位置变为course_num号课程，否则重新产生一个新的course_num
                                    matrix_c, update_ST, update_TT = update_timetable(matrix_c, update_ST, update_TT,
                                                                                      new_positions_c[0],
                                                                                      trans_position,
                                                                                      start_week, end_week, week_type,
                                                                                      students, teachers, stus, tea,
                                                                                      task_num,
                                                                                      classroom_list)  # 删除一个矩阵a中的课程

                                    # 当对一个课程号课程进行改变后，修改schemesList表i号排课方案中course_num课程的上课信息
                                    update_task = update.updated_scheme(update_scheme[index_num], new_positions_c[0],
                                                                        trans_position, classroom_list)
                                    # 对于改变课程信息的课程在原有方案中删除，将update_courselist添加到排课方案列表中
                                    update_scheme[index_num] = update_task
                            del positions[0]
                            del new_positions_c[0]

            # 完成个体i的位置更新后，需同步到学生和老师的信息更新
            update_RTmatrix.append(matrix_c)
            update_schemeslist.append(update_scheme)
            update_STmatrix_filled.append(update_ST)
            update_TTmatrix_filled.append(update_TT)

        copy_schemesList = copy.deepcopy(update_schemeslist)
        # 重新计算适应度值
        fitness___ = Target.target_fun(update_RTmatrix, update_STmatrix_filled, update_TTmatrix_filled, buildings_dis,
                                       len(students), len(teachers))
        # 快速非支配排序、拥挤度计算
        newParetofrontiers = Super.super(fitness___)
        # 更新个体最优
        lion_p, RTlion_p, fitness_p, s_t_p, t_t_p = update.update_pbest(copy_schemesList, update_RTmatrix, fitness___,
                                                                        update_STmatrix_filled, update_TTmatrix_filled,
                                                                        lion_p, RTlion_p, fitness_p, s_t_p, t_t_p)
        # 更新全局最优(狮王位置)
        lion_g, lion_fitness, RTlion_g = archiving.select_global_best(copy_schemesList, lion_g, lion_fitness,
                                                                      newParetofrontiers, update_RTmatrix, RTlion_g)
        print("迭代次数：", t + 1)
        print("学生教师方差：", lion_fitness[1], "教室空闲率：", lion_fitness[2], "平均距离：", lion_fitness[3])
        x.append(t + 1)
        y1.append(lion_fitness[1])
        y2.append(lion_fitness[2])
        y3.append(lion_fitness[3])
    return lion_g, lion_fitness, x, y1, y2, y3, RTlion_g


def calculate_position(position_a, position_b, classroomlist):
    if len(position_a) != len(position_b):
        return [], position_a

    position = []
    new_position_a = []
    right1 = len(classroomlist) - 1
    right2 = config.num_days * config.periods_per_day - 1
    for i in range(len(position_a)):
        pos = tuple(2 * a - b for a, b in zip(position_a[i], position_b[i]))
        if (not any(p < 0 for p in pos)) and (pos[0] <= right1) and (pos[1] <= right2):
            # 如果位置变换之后合法,添加到新位置列表和新的position_a中
            position.append(pos)
            new_position_a.append(position_a[i])
    return position, new_position_a


def find_all_element_positions(matrix, element, start_week):
    positions = []  # 存储所有值等于 element 的位置
    matrix_arr = np.array(matrix[start_week - 1], object)
    indices = np.array(np.where(matrix_arr != ""))
    for j in range(len(indices[0])):
        if matrix_arr[indices[0][j]][indices[1][j]][0] == element:
            positions.append(tuple(indices[:, j]))
    return positions


def is_conflict(matrix, update_ST, update_TT, position, start_week, end_week, week_type, students, teachers, stus, tea):
    # 冲突
    conflict = False
    room = position[0]
    time_plot = position[1]
    # 检查指定位置是否为空----添加周
    # 连续周
    if week_type == 0:
        for week in range(start_week, end_week + 1):
            # 教室时间冲突检测
            if matrix[week - 1][room][time_plot] != "":
                conflict = True
                break
            # 教师时间冲突
            if update_TT[week - 1][teachers.index(tea)][time_plot] != "":
                conflict = True
                break
            # 学生时间冲突
            for stu in stus:
                if update_ST[week - 1][students.index(stu)][time_plot] != "":
                    conflict = True
                    break
            if conflict:
                break
        return conflict
    # 单周
    if week_type == 1:
        for week in range(start_week, end_week + 1):
            if week % 2 == 1:
                # 教室时间冲突检测
                if matrix[week - 1][room][time_plot] != "":
                    conflict = True
                    break
                # 教师时间冲突
                if update_TT[week - 1][teachers.index(tea)][time_plot] != "":
                    conflict = True
                    break
                # 学生时间冲突
                for stu in stus:
                    if update_ST[week - 1][students.index(stu)][time_plot] != "":
                        conflict = True
                        break
                if conflict:
                    break
        return conflict
    # 双周
    if week_type == 2:
        for week in range(start_week, end_week + 1):
            if week % 2 == 0:
                # 教室时间冲突检测
                if matrix[week - 1][room][time_plot] != "":
                    conflict = True
                    break
                # 教师时间冲突
                if update_TT[week - 1][teachers.index(tea)][time_plot] != "":
                    conflict = True
                    break
                # 学生时间冲突
                for stu in stus:
                    if update_ST[week - 1][students.index(stu)][time_plot] != "":
                        conflict = True
                        break
                if conflict:
                    break
        return conflict


def update_timetable(matrix, update_ST, update_TT, position_a, position_b, start_week, end_week, week_type, students,
                     teachers, stus, tea, task_num, classroom_list):
    # 更新时间表
    if week_type == 0:
        for i in range(start_week, end_week + 1):
            matrix[i - 1][position_a[0]][position_a[1]] = ""
            matrix[i - 1][position_b[0]][position_b[1]] = (task_num, classroom_list[position_b[0]][1], len(stus))
            update_TT[i - 1][teachers.index(tea)][position_a[1]] = ""
            update_TT[i - 1][teachers.index(tea)][position_b[1]] = (task_num, classroom_list[position_b[0]])
            for stu in stus:
                update_ST[i - 1][students.index(stu)][position_a[1]] = ""
                update_ST[i - 1][students.index(stu)][position_b[1]] = (task_num, classroom_list[position_b[0]])
    if week_type == 1:
        for i in range(start_week, end_week + 1):
            if week_type % 2 == 1:
                matrix[i - 1][position_a[0]][position_a[1]] = ""
                matrix[i - 1][position_b[0]][position_b[1]] = (task_num, classroom_list[position_b[0]][1], len(stus))
                update_TT[i - 1][teachers.index(tea)][position_a[1]] = ""
                update_TT[i - 1][teachers.index(tea)][position_b[1]] = (task_num, classroom_list[position_b[0]])
                for stu in stus:
                    update_ST[i - 1][students.index(stu)][position_a[1]] = ""
                    update_ST[i - 1][students.index(stu)][position_b[1]] = (task_num, classroom_list[position_b[0]])
    if week_type == 2:
        for i in range(start_week, end_week + 1):
            if week_type % 2 == 0:
                matrix[i - 1][position_a[0]][position_a[1]] = ""
                matrix[i - 1][position_b[0]][position_b[1]] = (task_num, classroom_list[position_b[0]][1], len(stus))
                update_TT[i - 1][teachers.index(tea)][position_a[1]] = ""
                update_TT[i - 1][teachers.index(tea)][position_b[1]] = (task_num, classroom_list[position_b[0]])
                for stu in stus:
                    update_ST[i - 1][students.index(stu)][position_a[1]] = ""
                    update_ST[i - 1][students.index(stu)][position_b[1]] = (task_num, classroom_list[position_b[0]])
    return matrix, update_ST, update_TT


# #初始化个体最优值
def init_pbest(init_population, init_popuRT, fitness_, int_ss, int_ts):  # 第一次迭代最优个体就是本身
    return init_population, init_popuRT, fitness_, int_ss, int_ts
